precision mediump float; // 中精度浮点数

uniform float times;
varying vec2 vUV;
varying vec3 vPosition;
varying vec2 vResolution;
uniform sampler2D u_texture;

// ========= Noise ===========

#define MOD3 vec3(.1031, .11369, .13787)
//#define MOD3 vec3(443.8975,397.2973, 491.1871)
float hash31( vec3 p3 ){
    p3 = fract( p3 * MOD3 );
    p3 += dot( p3 , p3.yzx + 19.19 );
    return - 1.0 + 2.0 * fract( ( p3.x + p3.y ) * p3.z );
}

vec3 hash33( vec3 p3 ){
    p3 = fract( p3 * MOD3 );
    p3 += dot( p3 , p3.yxz + 19.19 );
    return - 1.0 + 2.0 * fract( vec3( ( p3.x + p3.y ) * p3.z , ( p3.x + p3.z ) * p3.y , ( p3.y + p3.z ) * p3.x ) );
}

float value_noise( vec3 p ){
    vec3 pi = floor( p );
    vec3 pf = p - pi;

    vec3 w = pf * pf * ( 3.0 - 2.0 * pf );

    return mix( mix( mix( hash31( pi + vec3( 0 , 0 , 0 ) ) , hash31( pi + vec3( 1 , 0 , 0 ) ) , w.x ) , mix( hash31( pi + vec3( 0 , 0 , 1 ) ) , hash31( pi + vec3( 1 , 0 , 1 ) ) , w.x ) , w.z ) , mix( mix( hash31( pi + vec3( 0 , 1 , 0 ) ) , hash31( pi + vec3( 1 , 1 , 0 ) ) , w.x ) , mix( hash31( pi + vec3( 0 , 1 , 1 ) ) , hash31( pi + vec3( 1 , 1 , 1 ) ) , w.x ) , w.z ) , w.y );
}

float perlin_noise( vec3 p ){
    vec3 pi = floor( p );
    vec3 pf = p - pi;

    vec3 w = pf * pf * ( 3.0 - 2.0 * pf );

    return mix( mix( mix( dot( pf - vec3( 0 , 0 , 0 ) , hash33( pi + vec3( 0 , 0 , 0 ) ) ) , dot( pf - vec3( 1 , 0 , 0 ) , hash33( pi + vec3( 1 , 0 , 0 ) ) ) , w.x ) , mix( dot( pf - vec3( 0 , 0 , 1 ) , hash33( pi + vec3( 0 , 0 , 1 ) ) ) , dot( pf - vec3( 1 , 0 , 1 ) , hash33( pi + vec3( 1 , 0 , 1 ) ) ) , w.x ) , w.z ) , mix( mix( dot( pf - vec3( 0 , 1 , 0 ) , hash33( pi + vec3( 0 , 1 , 0 ) ) ) , dot( pf - vec3( 1 , 1 , 0 ) , hash33( pi + vec3( 1 , 1 , 0 ) ) ) , w.x ) , mix( dot( pf - vec3( 0 , 1 , 1 ) , hash33( pi + vec3( 0 , 1 , 1 ) ) ) , dot( pf - vec3( 1 , 1 , 1 ) , hash33( pi + vec3( 1 , 1 , 1 ) ) ) , w.x ) , w.z ) , w.y );
}

// 将深度纹理转换为法线纹理的函数
vec3 depthToNormal( sampler2D depthTexture , vec2 texCoord , vec2 depthTextureSize ){
    float depthValue = texture2D( depthTexture , texCoord ).r;

    // 将深度值转换为线性深度（如果使用非线性深度缓冲，则需要进行这一步）
    // 对于线性深度缓冲，您可以跳过这一步。
    // float near = 0.1; // 近裁剪面距离
    // float far = 100.0; // 远裁剪面距离
    // float linearDepth = 2.0 * near / ( far + near - depthValue * ( far - near ) );

    // 计算视图空间中一个像素的大小
    vec2 pixelSize = vec2( 1.0 / depthTextureSize.x , 1.0 / depthTextureSize.y );

    // 采样相邻像素的深度值
    float depthLeft = texture2D( depthTexture , texCoord - vec2( pixelSize.x , 0.0 ) ).r;
    float depthRight = texture2D( depthTexture , texCoord + vec2( pixelSize.x , 0.0 ) ).r;
    float depthUp = texture2D( depthTexture , texCoord - vec2( 0.0 , pixelSize.y ) ).r;
    float depthDown = texture2D( depthTexture , texCoord + vec2( 0.0 , pixelSize.y ) ).r;

    // 计算视图空间法线（使用中心差分法）
    vec3 normalView;
    normalView.x = ( depthLeft - depthRight ) * 0.5;
    normalView.y = ( depthDown - depthUp ) * 0.5;
    normalView.z = 1.0;

    // 将视图空间法线转换为世界空间
    mat4 viewInverseTransposeMatrix = mat4( 1.0 ); // 在这里设置您的视图矩阵的逆转置矩阵
    vec3 normalWorld = ( viewInverseTransposeMatrix * vec4( normalView , 0.0 ) ).xyz;
    // 将法线向量映射到 [0, 1] 范围，并将其表示为彩色像素
    return normalize( normalWorld ) * 0.5 + 0.5;
}

void main( ){

    vec3 outPutColor = vec3( perlin_noise( vPosition / 100. + vec3( times ) ) );

    // outPutColor = texture2D( u_texture , vUV ).rgb;
    outPutColor = depthToNormal( u_texture , vUV , vResolution );

    gl_FragColor = vec4( outPutColor , 1.0 );
}